//
//  PhotoBrowserAnimator.swift
//  MicroBlog
//
//  Created by 002 on 15/10/29.
//  Copyright © 2015年 002. All rights reserved.
//

import UIKit

// MARK: - 照片的转场动画 modal 协议
protocol PhotoBrowserPresentDelegate : NSObjectProtocol {
    
    // 所选中图片
    func imageViewForPresent(indexPath : NSIndexPath) -> UIImageView
    
    // 图片在 window 中的起始位置
    func photoBrowserPresetnFromRect(indexPath : NSIndexPath) -> CGRect
    
    // 图片在 window 中的目标位置
    func photoBrowserPresetnToRect(indexPath : NSIndexPath) -> CGRect
}

// MARK: - 照片转场动画的 dissmiss 协议
protocol PhotoBrowserDissmissDelegate : NSObjectProtocol {
    
    // dismiss所选的中图像 (包含了起始frame)
    func imageViewForDissmiss() -> UIImageView
    
    // dismiss图像的索引
    func indexPathForDissmiss() -> NSIndexPath
    
}

/// 提供转场动画‘代理’
class PhotoBrowserAnimator: NSObject,UIViewControllerTransitioningDelegate {
    
    // modal 代理对象
    weak var presentDelegate : PhotoBrowserPresentDelegate?
    
    // dismiss 代理对象
    weak var dismissDelegate : PhotoBrowserDissmissDelegate?
    
    // 动画图像索引
    var indexPath : NSIndexPath?
    
    // 是否 modal展现 的标记
    private var isPresent : Bool = true
    
    // 返回 model 展现的‘动画对象’
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        
        isPresent = true
        
        return self
    }
    // 返回 dismiss 展现的‘动画对象’
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        
        isPresent = false
        
        return self
    }
}

/// 具体动画效果
extension PhotoBrowserAnimator : UIViewControllerAnimatedTransitioning {
    
    // MARK: 动画时长
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.5
    }

    /// 实现具体的动画效果 - 一旦实现了此方法，所有的动画代码都交由程序员负责
    /// :param: transitionContext 转场动画上下文 - 提供转场动画所需的素材
    /// 如果此方法实现为空，那么无法完成 model 操作
    /**
    1. 容器视图 － 会将 Modal 要展现的视图包装在容器视图中
    存放的视图要显示－必须自己指定大小！不会通过自动布局填满屏幕
    2. viewControllerForKey: fromVC / toVC
    3. viewForKey: fromView / toView
    4. completeTransition: 无论转场是否被取消，都必须调用
    否则，系统不做其他事件处理！
    */
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        
        let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
        print("fromVC:\(fromVC)")
        
        let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
        print("toVC\(toVC)")
        
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
        print("fromView:\(fromView)")
        
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)
        print("toView:\(toView)")
        
        isPresent ? presentAnimation(transitionContext) : dismissAnimation(transitionContext)
    }
    
    // 展现 modal 的转场动画
    func presentAnimation(transitionContext: UIViewControllerContextTransitioning) {
        
        // 判断参数是否存在
        guard let presentDelegate = self.presentDelegate,indexPath = self.indexPath else {
            return
        }
    
        // 1. 目标视图
        // 1) 获取 modal 要展现的控制器的根视图
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)
        
        // 2). 添加视图到容器视图中
        transitionContext.containerView()?.addSubview(toView!)
        
        // 2. 获取目标控制器 - 照片查看控制器
        let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as! PhotoBrowserViewController
        
        // 隐藏collectionView
        toVC.collectionView.hidden = true
        
        // 3. 图像视图
        // 1) 获取 图像视图
        let imageView = presentDelegate.imageViewForPresent(self.indexPath!)
        
        // 2) 设置图像视图起始位置
        imageView.frame = presentDelegate.photoBrowserPresetnFromRect(indexPath)
        imageView.alpha = 0
        
        // 3）添加到容器视图中
        transitionContext.containerView()?.addSubview(imageView)
        toView?.alpha = 0
        // 4. 执行动画
        UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
            
            // 图像视图目标位置
            imageView.frame = presentDelegate.photoBrowserPresetnToRect(self.indexPath!)
//            imageView.alpha = 1
            toView?.alpha = 1
            
            }) { (_) -> Void in
                
                // 恢复显示目标控制器的视图
                toVC.collectionView.hidden = false
                
                // 动画视图从父视图中移除
                imageView.removeFromSuperview()
                
                // 告诉系统转场动画完成，让系统接管控制权
                transitionContext.completeTransition(true)
        }
    }
    
    // 展现 dismiss 的转场动画
    func dismissAnimation(transitionContext: UIViewControllerContextTransitioning) {
        
        // 会把属性变成局部变量，后续的闭包中不需要 self，也不需要考虑解包！
        guard let dismissDelegate = self.dismissDelegate,presentDelegate = self.presentDelegate else {
            return
        }
        
        // 1. 获取根视图并移除
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
        fromView?.removeFromSuperview()
        
        // 2. 获取照片视图
        let imageView = dismissDelegate.imageViewForDissmiss()
        // 添加到容器视图中
        transitionContext.containerView()?.addSubview(imageView)
        
        // 3. 获取 dissmiss 的indexPath
        let indexPath = dismissDelegate.indexPathForDissmiss()
        
        // 4. 动画效果添加控件
        UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
            
            // 还原照片位置
            imageView.frame = presentDelegate.photoBrowserPresetnFromRect(indexPath)
            
            fromView?.alpha = 0
            
            }) { (_) -> Void in
                
                // 动画执行完毕移除照片视图
                imageView.removeFromSuperview()
                
                // 告诉系统转场动画完成，让系统接管控制权
                transitionContext.completeTransition(true)
        }
    }
    
    //MARK: - 设置 展现动画代理参数
    func setDelegateParams(presentDelegate : PhotoBrowserPresentDelegate,dismissDelegate : PhotoBrowserDissmissDelegate, indexPath : NSIndexPath) {
    
        self.presentDelegate = presentDelegate
        self.indexPath = indexPath
        self.dismissDelegate = dismissDelegate
    }
}